package main

import (
	"context"
	"embed"
	"fmt"
	"os"
	"path/filepath"
	"runtime"

	"lan-file-transfer/core"
	"lan-file-transfer/models"
	"lan-file-transfer/server"

	"github.com/wailsapp/wails/v2"
	"github.com/wailsapp/wails/v2/pkg/options"
	"github.com/wailsapp/wails/v2/pkg/options/assetserver"
	wruntime "github.com/wailsapp/wails/v2/pkg/runtime"
)

//go:embed all:frontend/src
var assets embed.FS

//go:embed all:web
var webFS embed.FS

// App 应用结构体
type App struct {
	ctx              context.Context
	server           *server.Server
	fileManager      *core.FileManager
	securityMgr      *core.SecurityManager
	configMgr        *core.ConfigManager
	tlsManager       *core.TLSManager
	password         string
	lastFolderPath   string // 记住上次选择文件夹的路径
	lastFilePath     string // 记住上次选择文件的路径
}

// NewApp 创建应用实例
func NewApp() *App {
	// 获取应用数据目录
	dataDir := getDataDir()

	// 创建TLS管理器
	tlsManager := core.NewTLSManager(dataDir)

	// 确保证书存在（自动生成）
	tlsEnabled := true
	if err := tlsManager.EnsureCertificates(); err != nil {
		// 证书生成失败，降级到HTTP模式
		fmt.Println("证书生成失败，将使用HTTP模式:", err)
		tlsEnabled = false
	}

	fileManager := core.NewFileManager()
	configMgr := core.NewConfigManager()

	// 生成默认密码
	password := core.GeneratePassword()
	securityMgr := core.NewSecurityManager(password)

	// 创建服务器（传入TLS配置）
	srv := server.NewServer(
		fileManager,
		securityMgr,
		configMgr,
		&webFS,
		tlsEnabled,
		tlsManager.GetCertPath(),
		tlsManager.GetKeyPath(),
	)

	return &App{
		server:      srv,
		fileManager: fileManager,
		securityMgr: securityMgr,
		configMgr:   configMgr,
		tlsManager:  tlsManager,
		password:    password,
	}
}

// startup 在应用启动时调用
func (a *App) startup(ctx context.Context) {
	a.ctx = ctx
}

// shutdown 在应用关闭前调用
func (a *App) shutdown(ctx context.Context) {
	// 停止服务器
	if a.server.GetState() == models.StateRunning {
		a.server.Stop()
	}

	// 保存配置
	a.configMgr.Save()
}

// StartServer 启动服务器
func (a *App) StartServer(port int, password string) error {
	// 设置端口
	a.configMgr.SetPort(port)

	// 设置密码
	a.password = password
	a.securityMgr.SetPassword(password)
	a.configMgr.SetPassword(password)

	// 启动服务器
	if err := a.server.Start(); err != nil {
		return fmt.Errorf("启动服务器失败: %w", err)
	}

	return nil
}

// StopServer 停止服务器
func (a *App) StopServer() error {
	return a.server.Stop()
}

// GetServerState 获取服务器状态
func (a *App) GetServerState() string {
	return string(a.server.GetState())
}

// GetAccessURLs 获取访问地址列表
func (a *App) GetAccessURLs() []string {
	ips := core.GetLocalIPs()
	port := a.server.GetPort()

	// 根据TLS配置决定协议
	protocol := "http"
	if a.server.IsTLSEnabled() {
		protocol = "https"
	}

	urls := make([]string, len(ips))
	for i, ip := range ips {
		urls[i] = fmt.Sprintf("%s://%s:%d", protocol, ip, port)
	}

	if len(urls) == 0 {
		urls = append(urls, fmt.Sprintf("%s://localhost:%d", protocol, port))
	}

	return urls
}

// GetPassword 获取当前密码
func (a *App) GetPassword() string {
	return a.password
}

// getDataDir 获取应用数据目录
func getDataDir() string {
	homeDir, _ := os.UserHomeDir()
	var dataDir string

	switch runtime.GOOS {
	case "darwin":
		// macOS: ~/Library/Application Support/lan-file-transfer
		dataDir = filepath.Join(homeDir, "Library", "Application Support", "lan-file-transfer")
	case "windows":
		// Windows: %APPDATA%\lan-file-transfer
		dataDir = filepath.Join(homeDir, "AppData", "Roaming", "lan-file-transfer")
	default:
		// Linux: ~/.config/lan-file-transfer
		dataDir = filepath.Join(homeDir, ".config", "lan-file-transfer")
	}

	// 确保目录存在
	os.MkdirAll(dataDir, 0755)

	return dataDir
}

// AddPaths 添加文件(支持多选)
func (a *App) AddPaths() error {
	// 使用文件选择对话框(支持多选文件)
	selectedPaths, err := wruntime.OpenMultipleFilesDialog(a.ctx, wruntime.OpenDialogOptions{
		Title: "选择要共享的文件",
	})

	if err != nil || len(selectedPaths) == 0 {
		return err
	}

	// 处理所有选中的路径
	for _, path := range selectedPaths {
		if err := a.AddPath(path); err != nil {
			// 继续处理其他文件,不中断
			continue
		}
	}

	return nil
}

// AddPath 添加单个路径(自动判断是文件还是文件夹)
func (a *App) AddPath(path string) error {
	info, err := os.Stat(path)
	if err != nil {
		return err
	}

	var fileInfo *models.FileInfo

	if info.IsDir() {
		// 添加文件夹
		fileInfo, err = a.fileManager.AddDirectory(path)
	} else {
		// 添加文件
		fileInfo, err = a.fileManager.AddFile(path)
	}

	if err != nil {
		return err
	}

	// 触发前端事件
	wruntime.EventsEmit(a.ctx, "file_added", fileInfo)
	return nil
}

// AddFiles 添加文件(保留兼容性)
func (a *App) AddFiles() error {
	// 确定默认打开路径:如果有上次路径,使用其父目录
	defaultDir := ""
	if a.lastFilePath != "" {
		// 获取上次路径的父目录
		defaultDir = filepath.Dir(a.lastFilePath)
	}

	files, err := wruntime.OpenMultipleFilesDialog(a.ctx, wruntime.OpenDialogOptions{
		Title:            "选择要共享的文件",
		DefaultDirectory: defaultDir,
	})

	if err != nil {
		return err
	}

	// 如果选择了文件,保存第一个文件的路径
	if len(files) > 0 {
		a.lastFilePath = files[0]
	}

	for _, filePath := range files {
		fileInfo, err := a.fileManager.AddFile(filePath)
		if err != nil {
			continue
		}
		wruntime.EventsEmit(a.ctx, "file_added", fileInfo)
	}

	return nil
}

// AddFolder 添加文件夹
func (a *App) AddFolder() error {
	// 确定默认打开路径:如果有上次路径,使用其父目录
	defaultDir := ""
	if a.lastFolderPath != "" {
		// 获取上次路径的父目录
		defaultDir = filepath.Dir(a.lastFolderPath)
	}

	folderPath, err := wruntime.OpenDirectoryDialog(a.ctx, wruntime.OpenDialogOptions{
		Title:            "选择要共享的文件夹",
		DefaultDirectory: defaultDir,
	})

	if err != nil {
		return err
	}

	if folderPath == "" {
		return nil
	}

	// 保存这次选择的路径
	a.lastFolderPath = folderPath

	fileInfo, err := a.fileManager.AddDirectory(folderPath)
	if err != nil {
		return err
	}

	wruntime.EventsEmit(a.ctx, "file_added", fileInfo)
	return nil
}

// RemoveFile 移除文件
func (a *App) RemoveFile(fileID string) error {
	return a.fileManager.RemoveFile(fileID)
}

// ClearFiles 清空所有文件
func (a *App) ClearFiles() error {
	a.fileManager.Clear()
	return nil
}

// GetFiles 获取文件列表
func (a *App) GetFiles() []*models.FileInfo {
	return a.fileManager.GetAllFiles()
}

// GetFileStats 获取文件统计
func (a *App) GetFileStats() map[string]interface{} {
	return map[string]interface{}{
		"count": a.fileManager.GetFileCount(),
		"size":  a.fileManager.GetTotalSize(),
	}
}

func main() {
	// 创建应用实例
	app := NewApp()

	// 创建应用
	err := wails.Run(&options.App{
		Title:  "局域网文件传输工具",
		Width:  1024,
		Height: 768,
		AssetServer: &assetserver.Options{
			Assets: assets,
		},
		BackgroundColour: &options.RGBA{R: 245, G: 245, B: 245, A: 1},
		OnStartup:        app.startup,
		OnShutdown:       app.shutdown,
		Bind: []interface{}{
			app,
		},
	})

	if err != nil {
		println("Error:", err.Error())
	}
}
